package com.usian.filter;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.usian.utils.JWTUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

@Component
public class LoginFilter implements GlobalFilter, Ordered {

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //获取请求路劲  除了登录路劲 login  以外 其他都拦截
        String path= exchange.getRequest().getURI().getPath();
        System.out.println(path);

        if(path.contains("login")){
            //登录 放行
            return chain.filter(exchange);
        }else{
            //token  header 请求头
            String token = exchange.getRequest().getHeaders().getFirst("token");
            //校验token 有效期
            String userId =(String)redisTemplate.boundValueOps(token).get();
            if(StringUtils.isBlank(token) || StringUtils.isBlank(userId)){
                //token 无效  返回错误信息码
                ServerHttpResponse response = exchange.getResponse();
                JSONObject message = new JSONObject();
                message.put("code", -1);
                message.put("errorMessage", "token校验失败请重新登录");
                byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);
                DataBuffer buffer = response.bufferFactory().wrap(bits);
                response.setStatusCode(HttpStatus.OK);
                //指定编码，否则在浏览器中会中文乱码
                response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
                return response.writeWith(Mono.just(buffer));
            }else{

                try {
                    //token 有效  转发下游服务使用token信息
                    DecodedJWT verify = JWTUtils.verify(token);
                    String id = verify.getClaim("id").asString();

                    //中文转码，避免乱码
                    String username = verify.getClaim("username").asString();
                    String username1 = URLEncoder.encode(username,"UTF-8");

                    System.out.println("网关过滤器 解析 token [id="+id+",username="+username+"]");

                    ServerHttpRequest serverHttpRequest = exchange.getRequest().mutate().headers(httpHeaders -> {
                        httpHeaders.add("id", id);
                        httpHeaders.add("username", username1);
                    }).build();
                    exchange.mutate().request(serverHttpRequest).build();
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
